using SmartCommunity.Models;
using Mapster;
using Microsoft.EntityFrameworkCore;
using SmartCommunity.Services.Community;

namespace SmartCommunity.Services.Workorder
{
    /// <summary>
    /// 服务类：工单池
    /// </summary>
    public class WorkOrderService : BaseService<WorkOrderEntity>
    {
        #region 构造函数
        protected readonly SCDBContext ctx;
        public WorkOrderService(SCDBContext ctx)
        {
            this.ctx = ctx;
        }
        #endregion

        #region 数据查询 
        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<WorkOrderDto>> FindPagedList(WorkOrderQuery workOrderQuery, Pager pager, LoginUser user)
        {
            var query = ctx.WorkOrders.AsNoTracking().Where(workOrderQuery.GetQueryExpression());
            var data = await FindPagedList(query, pager, o => o.OrderByDescending(t => t.CreatedTime));
            var pageDto =  data.Map(o => o.Adapt<WorkOrderDto>());
            await MergeEnumName(pageDto.DataList);
            return pageDto;
        }

        private async Task MergeEnumName(IEnumerable<WorkOrderDto> dtos)
        {
            var dicts = await ctx.Dicts.Include(a => a.DictItems).Where(a => a.DictType.StartsWith("WorkOrder")).ToListAsync();
            var typeMap = dicts.SingleOrDefault(a => a.DictType == "WorkOrderType")!.DictItems.ToDictionary(k => k.DictValue, v => v.DictLabel);
            var statusMap = dicts.SingleOrDefault(a => a.DictType == "WorkOrderStatus")!.DictItems.ToDictionary(k => k.DictValue, v => v.DictLabel);
            foreach (var d in dtos)
            {
                if (typeMap != null && typeMap.TryGetValue(d.OrderType.ToString(), out var tn)) d.OrderTypeName = tn;
                if (statusMap != null && statusMap.TryGetValue(d.OrderStatus.ToString(), out var un)) d.OrderStatusName = un;
            }
        }
        /// <summary>
        /// 根据工单池ID查询
        /// </summary>
        public async Task<WorkOrderDto> FindWorkOrderById(Guid orderId)
        {
            var entity = await FindById(orderId);
            return entity.Adapt<WorkOrderDto>();
        }

        /// <summary>
        /// 根据ID查询实体类
        /// </summary>
        private async Task<WorkOrderEntity> FindById(Guid id)
        {
            return await ctx.WorkOrders.SingleOrDefaultAsync(a => a.OrderId == id)
                ?? throw new NotFoundException($"找不到指定的工单池,Id:{id}");
        }
        #endregion

        #region 增 删 改
        /// <summary>
        /// 新增工单池
        /// </summary>
        public async Task<WorkOrderDto> CreateWorkOrder(WorkOrderDto dto, LoginUser user)
        {
            // 新建对象
            var entity = new WorkOrderEntity();
            // 复制属性
             CopyDtoToEntity(dto, entity, user, true);
            var prefix = "CP" + DateTime.Now.ToString("yyyyMMdd") + (dto.OrderType.ToString() ?? "").PadLeft(2, '0');
            var last = await ctx.WorkOrders.Where(a => a.OrderNo.StartsWith(prefix)).ToListAsync();
            var maxNo = last.Any() ? int.Parse(last.Max(t => t.OrderNo).Substring(prefix.Length + 1).TrimStart('0')) : 0;
            entity.OrderNo = prefix + (maxNo + 1).ToString().PadLeft(4, '0');
            entity.OrderStatus = 0;
            // 执行保存
            ctx.WorkOrders.Add(entity);
            await ctx.SaveChangesAsync();
            // 返回Dto
            return entity.Adapt<WorkOrderDto>();
        }

        /// <summary>
        /// 更新工单池
        /// </summary>
        public async Task UpdateWorkOrder(WorkOrderDto dto, LoginUser user)
        {
            // 原始数据
            var entity = await FindById(dto.OrderId);
            // 更新字段
            CopyDtoToEntity(dto, entity, user, false);
            // 执行更新
            await ctx.SaveChangesAsync();
        }

        /// <summary>
        /// 复制dto属性到实体字段
        /// </summary>
        private void CopyDtoToEntity(WorkOrderDto dto, WorkOrderEntity entity, LoginUser user, bool isNew)
        {
            entity.OrderType = dto.OrderType;
            entity.Description = dto.Description;
            entity.OrderStatus = dto.OrderStatus;
            entity.SubmitPerson = dto.SubmitPerson;
            entity.SubmitTel = dto.SubmitTel;
            entity.SubmitAreaId = dto.SubmitAreaId;
            entity.SubmitRoomId = dto.SubmitRoomId;
            entity.SubmitAddr = dto.SubmitAddr;
            entity.SubmitTime = dto.SubmitTime;
            entity.RateStars = dto.RateStars;
            entity.RateContent = dto.RateContent;
            entity.HandleUser = dto.HandleUser;
            entity.HandleUserName = dto.HandleUserName;
            entity.HandleResult = dto.HandleResult;

            // 记录操作人
            if (isNew)
            {
                entity.CreatedBy = user.Username;
                entity.CreatedTime = DateTime.Now;
                entity.SubmitTime = DateTime.Now;
            }
            entity.UpdatedBy = user.Username;
            entity.UpdatedTime = DateTime.Now;
        }

        /// <summary>
        /// 根据ID删除工单池
        /// </summary>
        public async Task DeleteByIds(IEnumerable<Guid> ids, LoginUser user)
        {
            var workOrders = await ctx.WorkOrders.Where(a => ids.Contains(a.OrderId)).ToListAsync();
            if (workOrders.Count != ids.Count())
            {
                throw new MessageException("查询出的数据和传入的ID不匹配，请刷新后再试。");
            }
            //TODO 判断是否能删除
            foreach (var entity in workOrders)
            {
                ctx.WorkOrders.Remove(entity);
            }
            // 提交事务
            await ctx.SaveChangesAsync();
        }
        #endregion
    }
}
